﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media.Media3D;
using System.Windows.Controls;
using System.Windows.Media;

namespace EveruWPF.Windows.V3D
{
    /// <summary>
    /// Allowes the Mouse interaction with GeometryModel3Ds
    /// </summary>
    public class V3DInteraction
    {
        public static readonly RoutedEvent GeometryMousedownEvent = EventManager.RegisterRoutedEvent("GeometryMousedown", RoutingStrategy.Bubble, typeof(GeometryMouseHandler), typeof(Viewport3D));
        public static void AddGeometryMousedownHandler(UIElement uie, GeometryMouseHandler handler)
        {
            if (uie != null)
            {
                uie.AddHandler(GeometryMousedownEvent, handler);
            }
        }
        public static void RemoveGeometryMousedownHandler(UIElement uie, GeometryMouseHandler handler)
        {
            if (uie != null)
            {
                uie.RemoveHandler(GeometryMousedownEvent, handler);
            }
        }
        
        static void V3DInteraction_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
            {
                ViewportHitTestHandler handler = new ViewportHitTestHandler();
                handler.StartHitTest((sender as Viewport3D), new HitTestHandlerResult(ViewportMouseDownTesthandlerResult), e.GetPosition((sender as Viewport3D)));
            }
        }
        private static void ViewportMouseDownTesthandlerResult(GeometryModel3D Result, Viewport3D Port)
        {
            GeometryMouseArgs args = new GeometryMouseArgs();
            args.RoutedEvent = GeometryMousedownEvent;
            args.Viewport = Port;
            args.Model = Result;

            Port.RaiseEvent(args);
        }




        public static readonly RoutedEvent GeometryMouseupEvent = EventManager.RegisterRoutedEvent("GeometryMouseup", RoutingStrategy.Bubble, typeof(GeometryMouseHandler), typeof(Viewport3D));
        public static void AddGeometryMouseupHandler(UIElement uie, GeometryMouseHandler handler)
        {
            if (uie != null)
            {
                uie.AddHandler(GeometryMouseupEvent, handler);
            }
        }
        public static void RemoveGeometryMouseupHandler(UIElement uie, GeometryMouseHandler handler)
        {
            if (uie != null)
            {
                uie.RemoveHandler(GeometryMouseupEvent, handler);
            }
        }
        
        static void V3DInteraction_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
            {
                ViewportHitTestHandler handler = new ViewportHitTestHandler();
                handler.StartHitTest((sender as Viewport3D), new HitTestHandlerResult(ViewportMouseUpTesthandlerResult), e.GetPosition((sender as Viewport3D)));
            }
        }
        private static void ViewportMouseUpTesthandlerResult(GeometryModel3D Result, Viewport3D Port)
        {
            GeometryMouseArgs args = new GeometryMouseArgs();
            args.RoutedEvent = GeometryMouseupEvent;
            args.Viewport = Port;
            args.Model = Result;

            Port.RaiseEvent(args);
        }




        public static readonly RoutedEvent GeometryRightMousedownEvent = EventManager.RegisterRoutedEvent("GeometryRightMousedown", RoutingStrategy.Bubble, typeof(GeometryMouseHandler), typeof(Viewport3D));
        public static void AddGeometryRightMousedownHandler(UIElement uie, GeometryMouseHandler handler)
        {
            if (uie != null)
            {
                uie.AddHandler(GeometryRightMousedownEvent, handler);
            }
        }
        public static void RemoveGeometryRightMousedownHandler(UIElement uie, GeometryMouseHandler handler)
        {
            if (uie != null)
            {
                uie.RemoveHandler(GeometryRightMousedownEvent, handler);
            }
        }

        static void V3DInteraction_RightMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.ChangedButton == System.Windows.Input.MouseButton.Right)
            {
                ViewportHitTestHandler handler = new ViewportHitTestHandler();
                handler.StartHitTest((sender as Viewport3D), new HitTestHandlerResult(ViewportRightMouseDownTesthandlerResult), e.GetPosition((sender as Viewport3D)));
            }
        }
        private static void ViewportRightMouseDownTesthandlerResult(GeometryModel3D Result, Viewport3D Port)
        {
            GeometryMouseArgs args = new GeometryMouseArgs();
            args.RoutedEvent = GeometryRightMousedownEvent;
            args.Viewport = Port;
            args.Model = Result;

            Port.RaiseEvent(args);
        }




        public static readonly RoutedEvent GeometryRightMouseupEvent = EventManager.RegisterRoutedEvent("GeometryRightMouseup", RoutingStrategy.Bubble, typeof(GeometryMouseHandler), typeof(Viewport3D));
        public static void AddGeometryRightMouseupHandler(UIElement uie, GeometryMouseHandler handler)
        {
            if (uie != null)
            {
                uie.AddHandler(GeometryRightMouseupEvent, handler);
            }
        }
        public static void RemoveGeometryRightMouseupHandler(UIElement uie, GeometryMouseHandler handler)
        {
            if (uie != null)
            {
                uie.RemoveHandler(GeometryRightMouseupEvent, handler);
            }
        }

        static void V3DInteraction_RightMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.ChangedButton == System.Windows.Input.MouseButton.Right)
            {
                ViewportHitTestHandler handler = new ViewportHitTestHandler();
                handler.StartHitTest((sender as Viewport3D), new HitTestHandlerResult(ViewportRightMouseUpTesthandlerResult), e.GetPosition((sender as Viewport3D)));
            }
        }
        private static void ViewportRightMouseUpTesthandlerResult(GeometryModel3D Result, Viewport3D Port)
        {
            GeometryMouseArgs args = new GeometryMouseArgs();
            args.RoutedEvent = GeometryRightMouseupEvent;
            args.Viewport = Port;
            args.Model = Result;

            Port.RaiseEvent(args);
        }



        public static DependencyProperty ListenInteractionProperty = DependencyProperty.RegisterAttached("ListenInteraction", typeof(bool), typeof(Viewport3D), new PropertyMetadata(false, new PropertyChangedCallback(ListenInteractionChanged)));
        public static void ListenInteractionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            if ((bool)args.NewValue == true)
            {
                (sender as Viewport3D).MouseDown += new System.Windows.Input.MouseButtonEventHandler(V3DInteraction_MouseDown);
                (sender as Viewport3D).MouseUp += new System.Windows.Input.MouseButtonEventHandler(V3DInteraction_MouseUp);
                (sender as Viewport3D).MouseDown += new System.Windows.Input.MouseButtonEventHandler(V3DInteraction_RightMouseDown);
                (sender as Viewport3D).MouseUp += new System.Windows.Input.MouseButtonEventHandler(V3DInteraction_RightMouseUp);
            }
            else
            {
                (sender as Viewport3D).MouseDown -= V3DInteraction_MouseDown;
                (sender as Viewport3D).MouseUp -= V3DInteraction_MouseUp;
                (sender as Viewport3D).MouseDown -= V3DInteraction_RightMouseDown;
                (sender as Viewport3D).MouseUp -= V3DInteraction_RightMouseUp;
             }
        }        
        public static void SetListenInteraction(DependencyObject obj, bool value)
        {
            obj.SetValue(ListenInteractionProperty, value);
        }
        public static bool GetListenInteraction(DependencyObject obj)
        {
            return (bool)obj.GetValue(ListenInteractionProperty);
        }





    }


    public delegate void GeometryMouseHandler(object sender, GeometryMouseArgs e);

}
